
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>定时器与时间轮 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>定时器与时间轮 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">时间轮算法的基本思想是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">时间轮算法的本质是一个循环数组，数组的每个槽位代表一个时间间隔。它就像一个钟表，时针每次移动一格，就执行对应格子上挂载的任务列表。这种机制可以将定时任务的调度复杂度降低到O(1)。</div>
          </div>
          <div class="card-source">来源: 二、时间轮算法详解 -> 1. 时间轮的基本概念与结构</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在高并发场景下，传统的Java定时器（如Timer或ScheduledThreadPoolExecutor）存在哪些核心性能瓶颈？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">传统Java定时器在高并发场景下主要有三个瓶颈：1. 数据结构效率问题：通常使用优先队列（小顶堆），插入和删除操作的时间复杂度为O(log n)。2. 线程资源消耗：大量任务可能导致线程资源耗尽。3. 内存占用：海量的定时任务对象会占用大量堆内存，增加GC压力。</div>
          </div>
          <div class="card-source">来源: 一、定时器详解 -> 1. 传统定时器的性能瓶颈</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">当定时任务的延迟时间超过单层时间轮的总跨度时，层级时间轮是如何解决这个问题的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">层级时间轮通过类似时钟的时、分、秒针机制来解决。当任务延迟超过第一层（如秒级）时间轮的总跨度时，任务会被放入精度更低、跨度更大的第二层（如分钟级）时间轮。当高层时间轮的某个时间槽到期后，其中的任务会被“降级”到底层时间轮中，以进行更精确的调度和执行。</div>
          </div>
          <div class="card-source">来源: 二、时间轮算法详解 -> 3. 层级时间轮设计思路</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Netty的HashedWheelTimer作为时间轮算法的经典实现，采用了哪些优化来提升性能？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Netty的HashedWheelTimer主要通过三项优化来提升性能：1. 使用了数组链表结构，降低锁竞争；2. 采用延迟初始化策略，减少资源浪费；3. 将任务执行与时间轮的推进过程分离，从而提高响应速度。</div>
          </div>
          <div class="card-source">来源: 三、时间轮在开源项目中的应用 -> 1. Netty HashedWheelTimer 源码剖析</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">设计</div>
          <div class="card-question">在设计时间轮时，需要在哪些方面进行精度与性能的权衡？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">设计</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">设计时间轮时需要在三个方面进行权衡：1. 槽位数量：槽位越多精度越高，但内存占用越大。2. 时间粒度：时间粒度越小精度越高，但CPU使用率也越高。3. 层级深度：层级越多支持的时间跨度越大，但实现复杂度也随之增加。</div>
          </div>
          <div class="card-source">来源: 四、自己动手实现一个时间轮定时器 -> 3. 处理精度与性能权衡</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在分布式系统中，如何结合时间轮和一致性哈希算法来设计分布式定时任务调度？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以通过一致性哈希算法来决定一个任务应该由哪个节点处理。当添加一个分布式任务时，首先根据任务ID通过一致性哈希算法计算出其归属的节点。如果目标节点是当前节点，则将任务添加到本地的时间轮中进行调度；否则，可以忽略或将任务转发给目标节点。</div>
          </div>
          <div class="card-source">来源: 六、分布式系统中的时间轮应用 -> 1. 分布式定时任务调度设计</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">时间轮算法在哪些场景下可能不是最佳选择？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">时间轮算法在以下三种场景中可能不适用：1. 需要精确到微秒级的定时要求，因为时间轮通常以毫秒为粒度。2. 任务执行时间远长于调度时间，此时性能瓶颈在于任务执行而非调度。3. 任务数量极少但延迟极大，这种情况下时间轮的空间效率优势不明显。</div>
          </div>
          <div class="card-source">来源: 七、时间轮的局限性与替代方案 -> 1. 时间轮不适用的场景分析</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在高并发环境下，可以采用哪些策略来减少时间轮的锁竞争？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档中提到了三种减少锁竞争的策略：1. 分段锁：为不同的时间槽使用不同的锁，以减小锁的粒度。2. 无锁队列：使用基于CAS操作的无锁数据结构来存储任务。3. 任务批处理：一次性获取并处理多个任务，减少加锁解锁的频率。</div>
          </div>
          <div class="card-source">来源: 五、时间轮实践 -> 2. 减少锁竞争的策略</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">当时间轮需要处理海量任务时，有哪些内存使用优化技巧？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档介绍了三种内存优化技巧：1. 对象池化：通过重用任务对象来避免频繁地创建和销毁对象。2. 懒加载：对于层级时间轮，只在需要时才创建上层时间轮，避免不必要的内存分配。3. 任务聚合：将多个相似的任务聚合成一个任务，以减少内存中对象的总数。</div>
          </div>
          <div class="card-source">来源: 五、时间轮实践 -> 3. 内存使用优化技巧</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
